package com.yunji.app.cabinet;

import com.google.common.collect.Lists;
import com.yunji.cabinet.business.DeviceBusiness;
import com.yunji.cabinet.cache.CabinetCache;
import com.yunji.cabinet.device.*;
import com.yunji.cabinet.device.factory.DeviceStrategyFactory;
import com.yunji.cabinet.dto.CabinetActivateDTO;
import com.yunji.cabinet.dto.DeviceBindDTO;
import com.yunji.cabinet.dto.device.DeviceCommandDTO;
import com.yunji.cabinet.dto.device.DeviceShoppingDTO;
import com.yunji.cabinet.params.DeviceEventParam;
import com.yunji.cabinet.service.ICabinetService;
import com.yunji.cabinet.vo.CodeUrlVO;
import com.yunji.cabinet.vo.DeviceEventVO;
import com.yunji.common.base.response.Response;
import com.yunji.common.base.response.ResponseHelper;
import com.yunji.common.utils.ExcelUtil;
import com.yunji.coffee.entity.dto.ICommonDeviceInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.Objects;

/**
 * @author : peter-zhu
 * @date : 2025/1/25 10:19
 * @description : TODO
 */
@RestController
@Api(tags = "设备")
@RequestMapping("/gateway/device")
@Slf4j
public class DeviceController {
    private static final String SHEET_NAME = "二维码地址";

    @Resource
    private DeviceBusiness deviceBusiness;

    @Resource
    private ICabinetService cabinetService;

    @GetMapping("/test")
    @ApiOperation("test")
    public void test() {
        String url = " http://127.0.0.1:62521/device/coffee";
        String s = DeviceSignatureUtil.get(url + "/test");
        System.out.println(s);
    }

    @GetMapping("/randomUrl")
    @ApiOperation("导出随机生成二维码链接")
    public void generateQRCode(@RequestParam("number") int nums, HttpServletResponse response) {
        List<CodeUrlVO> codeUrlVOS = deviceBusiness.generateQRCode(nums);
        ExcelUtil<CodeUrlVO> util = new ExcelUtil<>(CodeUrlVO.class);
        util.exportExcel(response, codeUrlVOS, SHEET_NAME);
    }

    @PostMapping("/bindCode")
    @ApiOperation("绑定二维码和芯片信息")
    public Response<?> bindQRCodeChip(@RequestBody @Valid DeviceBindDTO dto) {
        deviceBusiness.bindQRCodeChip(dto);
        return ResponseHelper.success("绑定成功");
    }

    @ApiOperation("激活并创建货柜")
    @PostMapping("/createCabinet")
    public Response<?> createCabinet(@RequestBody CabinetActivateDTO dto) {
        boolean b = deviceBusiness.createCabinet(dto);
        try {
            String imeiByQrcode = cabinetService.getImeiByQrcode(dto.getQrCode());
            if (b)
                DeviceCommandEngine.addCycleOnline(imeiByQrcode);
            DeviceCommandEngine.online(imeiByQrcode);
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            log.error("createCabinet ping失败 qrcode{}", dto.getQrCode());
        }
        return ResponseHelper.handle(b, "智能柜添加失败");
    }

    @ApiOperation("获取信号")
    @GetMapping("/getRssi")
    public Response<Integer> getRssi(@RequestParam("imei") String imei, @RequestParam("typeCode") String typeCode) {
        return ResponseHelper.success(DeviceStrategyFactory.getStrategy(typeCode).getRssi(imei));
    }

    @ApiOperation("顶部红外检测")
    @GetMapping("/topInfraredTest")
    public Response<List<Integer>> topInfraredTest(@RequestParam("imei") String imei, @RequestParam("typeCode") String typeCode) {
        DeviceCommandEngine strategy = DeviceStrategyFactory.getStrategy(typeCode);
        return ResponseHelper.success(strategy.topInfraredTest(imei));
    }

    @ApiOperation("补货开关检测")
    @GetMapping("/restockTest")
    public Response<?> restockTest(@RequestParam("imei") String imei, @RequestParam("typeCode") String typeCode) {
        boolean rs = true;
        if (ContainerTypeEnum.hasRestock(typeCode)) {
            rs = DeviceCommandEngine.executeCommand(new DeviceCommandDTO(DeviceEventEnum.FACTORY_TEST.name(),
                    DeviceCommandEnum.OPEN_RESTOCK.name(), imei));
        }
        if (rs)
            DeviceSpinService.validateCargoStatus(imei, typeCode);
        return ResponseHelper.handle(rs, "补货开关检测失败或超时");
    }

    @ApiOperation("出货开关检测")
    @GetMapping("/shippingTest")
    public Response<?> shippingTest(@RequestParam("imei") String imei, @RequestParam("typeCode") String typeCode) {
        DeviceCommandEngine strategy = DeviceStrategyFactory.getStrategy(typeCode);
        Boolean b = strategy.shippingTest(imei);
        if (b)
            DeviceSpinService.validateShopStatus(imei, typeCode);
        return ResponseHelper.handle(b, "出货失败");
    }

    @ApiOperation("根据二维码开补货仓")
    @GetMapping("/restockOpen/{qrCode}")
    public Response<?> restockOpen(@PathVariable("qrCode") String qrCode) {
        String imei = deviceBusiness.getImeiByQrCode(qrCode);
        return ResponseHelper.handle(DeviceCommandEngine.executeCommand(new DeviceCommandDTO(DeviceEventEnum.TEMPLATE_MODIFY.name(),
                DeviceCommandEnum.OPEN_RESTOCK.name(), imei)), "根据二维码开补货仓失败");
    }

    @ApiOperation("根据二维码开出货仓")
    @GetMapping("/shippingOpen/{qrCode}")
    public Response<?> shippingOpen(@PathVariable("qrCode") String qrCode) {
        String imei = deviceBusiness.getImeiByQrCode(qrCode);
        return ResponseHelper.handle(DeviceCommandEngine.executeCommand(new DeviceCommandDTO(DeviceEventEnum.TEMPLATE_MODIFY.name(),
                DeviceCommandEnum.OPEN_SHIPPING.name(), imei, Lists.newArrayList(new DeviceShoppingDTO(1,1)))), "根据二维码开出货仓失败");
    }

    @ApiOperation("分页查询设备日志")
    @PostMapping("/list")
    public Response<List<DeviceEventVO>> list(@Valid @RequestBody DeviceEventParam records) {
        List<DeviceEventVO> list = deviceBusiness.list(records);
        return ResponseHelper.successWithPage(list, records.getTotal());
    }

    @ApiOperation("导出设备日志")
    @PostMapping("/export")
    public void export(@RequestBody DeviceEventParam records, HttpServletResponse response) {
        List<DeviceEventVO> list = deviceBusiness.list(records);
        ExcelUtil<DeviceEventVO> util = new ExcelUtil<>(DeviceEventVO.class);
        util.exportExcel(response, list, "设备日志");
    }

    @ApiOperation("根据IMEI码查看设备最后一次上报状态")
    @GetMapping("/getDeviceInfo/{imei}")
    public Response<ICommonDeviceInfo> getDeviceInfo(@PathVariable("imei") String imei) {
        return ResponseHelper.success(DeviceInfoCache.getInfo(imei, Objects.requireNonNull(
                ContainerTypeEnum.getClass(CabinetCache.getTypeCode(imei)), "根据imei查询为null")));
    }
}
